
package com.yuanmei.views;

import android.app.Application;
import android.content.Context;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


import io.realm.Realm;

import static android.os.Environment.MEDIA_MOUNTED;
import com.github.promeg.pinyinhelper.Pinyin;
import com.github.promeg.tinypinyin.lexicons.android.cncity.CnCityDict;
import com.yuanmei.common.LogFile;
import com.yuanmei.datas.FetchTickDaemon;


public class QuickStockApplication extends Application {
    public static final String TAG = QuickStockApplication.class.getName();


    public interface NotifyMessageCallback {
        void onToastNotify(String notifyMessage);
        void onUpdateProgressNotify(int progressPercent);
        void onShowProgressBar();
        void onHideProgressBar();
    }
    private static NotifyMessageCallback sMessageCallback;
    private static final Object sMessageCallbackLock = new Object();

    public static void registerNotifyCallback(NotifyMessageCallback callback) {
        synchronized (sMessageCallbackLock) {
            sMessageCallback = callback;
        }
    }

    public static void unregisterNotifyCallback(NotifyMessageCallback callback) {
        synchronized (sMessageCallbackLock) {
            if (sMessageCallback == callback) {
                sMessageCallback = null;
            }
        }
    }

    public static void notifyToast(String message) {
        synchronized (sMessageCallbackLock) {
            if (sMessageCallback != null) {
                sMessageCallback.onToastNotify(message);
                try {
                    Thread.sleep(800); // 延迟1s，让toast显示
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void notifyProgress(int progressPercent) {
        synchronized (sMessageCallbackLock) {
            if (sMessageCallback != null) {
                sMessageCallback.onUpdateProgressNotify(progressPercent);
            }
        }
    }

    public static void showProgressBar() {
        synchronized (sMessageCallbackLock) {
            if (sMessageCallback != null) {
                sMessageCallback.onShowProgressBar();
            }
        }
    }

    public static void hideProgressBar() {
        synchronized (sMessageCallbackLock) {
            if (sMessageCallback != null) {
                sMessageCallback.onHideProgressBar();
            }
        }
    }

    private static ExecutorService sGitExecutor = Executors.newSingleThreadExecutor();
    public static void doSyncRunaable(Runnable r) {
        sGitExecutor.execute(r);
    }

    public class CrashExceptionHandler implements Thread.UncaughtExceptionHandler {
        private Thread.UncaughtExceptionHandler mDefaultHandler;
        private DateFormat formatter =
                new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.getDefault());
        private Context mContext;
        private String mCrashLogDir;

        public CrashExceptionHandler(Context contxt) {
            mContext = contxt;
            mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
//            String crash_dir = "crash";
//            if (MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ) {
//                mCrashLogDir = contxt.getExternalFilesDir(crash_dir).getAbsolutePath() ;
//            }else{
//                mCrashLogDir = contxt.getFilesDir().getAbsolutePath() + File.separator + crash_dir; ;
//            }
            mCrashLogDir = "/storage/emulated/0/Download/QuickStockCrashLog/";
        }

        @Override
        public void uncaughtException(Thread thread, Throwable e) {
            Log.e(TAG, "Fatal Uncaught Exception:" + e.getLocalizedMessage(), e);
            if (e != null) {
                String crashLogFile = saveCrashLogFile(e);
                Toast.makeText(mContext, "异常日志已保存到:" + crashLogFile, Toast.LENGTH_SHORT).show();
            } else {
                mDefaultHandler.uncaughtException(thread, e);
            }
        }

        private String saveCrashLogFile(Throwable exception) {
            StringBuffer sb = new StringBuffer();
            sb.append("Back traces starts." + "\n");
            Writer writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter(writer);
            exception.printStackTrace(printWriter);
            Throwable cause = exception.getCause();
            while (cause != null) {
                cause.printStackTrace(printWriter);
                cause = cause.getCause();
            }
            printWriter.close();

            String result = writer.toString();
            sb.append(result);
            sb.append("Back traces ends.\n" + "\n");
            try {
                String fileName = mCrashLogDir + File.separator + "crash-" +
                        formatter.format(System.currentTimeMillis()) + ".log";
                FileOutputStream fos = new FileOutputStream(fileName);
                fos.write(sb.toString().getBytes());
                fos.close();
                return fileName;
            } catch (Exception e) {
                Log.e(TAG, "saveCrashLogFile fail", e);
            }
            return null;
        }
    }


    @Override
    public void onCreate() {
        super.onCreate();
        LogFile.init(this);
//        if (!Utils.isApplicationDebuggable(this))
        {
            Thread.setDefaultUncaughtExceptionHandler(new CrashExceptionHandler(this));
        }
//        Utils.preDeleteRealTimeTickRealmFile(this.getFilesDir().getAbsolutePath());
        Realm.init(this); // 初始化realm，只能有1次
        Pinyin.init(Pinyin.newConfig().with(CnCityDict.getInstance(this)));
        com.github.mikephil.charting.utils.Utils.init(this);
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        FetchTickDaemon.getInstance().stop();
    }

}
